/*************************************** 定数 ***************************************/

Const = {
	Comment : {
		WIDTH_LENGTH : 51,
		CHARNAME_MIN_LENGTH : 3,
		CHARNAME_MAX_LENGTH : 16,
		SHORTCUT_MAX_LENGTH : 84,
		STR_MAX_LENGTH : 128,
		BALLON_LINE_LENGTH : 40,
		
		COOKIE_EXPIREDAY : 365,
		
		COOKIE_MAX_SAVE_COUNT : 5,
		
		dummy:null
	},
	
	CookieNames : [
		"MY_MACRO1",
		"MY_MACRO2",
		"MY_MACRO3",
		"MY_MACRO4",
		"MY_MACRO5"
	]
};

/*************************************** ユーティリティ ***************************************/
Comment = {};

Comment.Util = {
	/**
	 * 文字列の横幅を返す
	 * @param str
	 * @returns
	 */
	getStrWidth : function(str){
		len = 0;
		str = escape(str);
		for (var i = 0; i < str.length; i++, len++) {
			var temp = "";
			var maltiByte = false;
			if (str.charAt(i) == "%") {
				if (str.charAt(i+1) == "u") {
					
					len++;

					temp += str.charAt(i);
					i++;
					
					temp += str.charAt(i);
					i++;
					
					temp += str.charAt(i);
					i++;
					
					maltiByte = true;
				}

				temp += str.charAt(i);
				i++;
				
				temp += str.charAt(i);
				i++;
			}
			temp += str.charAt(i);
			
			// 半角カナか判定
			if(maltiByte && unescape(temp).match(/[\u0020-\u007E\uFF61-\uFF9F]/)){
				len--;
			}
		}

		return len;
	},

	splitStrLength : function (str, length){
		str1 = "", str2 = "";

		len = 0;

		addStr = function(char){
			if(len >= length){
				str2 += char;
			}
			else{
				str1 += char;
			}
		};

		str = escape(str);
		for (var i = 0; i < str.length; i++, len++) {
			var temp = "";
			var maltiByte = false;
			if (str.charAt(i) == "%") {
				if (str.charAt(i+1) == "u") {
					
					len++;

					temp += str.charAt(i);
					i++;
					
					temp += str.charAt(i);
					i++;
					
					temp += str.charAt(i);
					i++;
					
					maltiByte = true;
				}

				temp += str.charAt(i);
				i++;
				
				temp += str.charAt(i);
				i++;
			}
			temp += str.charAt(i);
			
			// 半角カナか判定
			if(maltiByte && unescape(temp).match(/[\u0020-\u007E\uFF61-\uFF9F]/)){
				len--;
			}
			addStr(temp);
		}
		str1 = unescape(str1);
		str2 = unescape(str2);

		return [str1 , str2];
	},

	showMessage : function(msg){
		$('#std_msg').html(msg);
	},

	optimizeLine : function(str){
		str = str.replace("  ", "　", "g");

		return str;
	},
	
	getArrayRand : function(arr){
		var rand = Math.floor( Math.random() * arr.length);
		return arr[rand];
	},

	optimizeShowLine : function(str){
		str = str.replace("<hp>", Comment.Util.getArrayRand(["1000", "100", "1"]), "g");
		str = str.replace("<pw>", Comment.Util.getArrayRand(["100", "50", "0"]), "g");
		str = str.replace("<pos>", Comment.Util.getArrayRand(["[A:1]", "[B:2]", "[C:3]"]), "g");
		str = str.replace("<cry>", Comment.Util.getArrayRand(["0", "12", "50"]), "g");
		
		str = str.replace(/<icon[1-7]>/, "");

		return str;
	},
	
	changeTextArea : function(selector, height, width){
		var target = $(selector);
		
		if(isFinite(height)){
			target.attr("rows", height);
		}
		
		if(isFinite(width)){
			target.attr("cols", width);
		}
	},
	
	alert : function(text){
		if($("#common_alert").html() == ""){
			$("#common_alert").dialog( {
				bgiframe : true,
				autoOpen : false,
				width : 300,
				resizable : false,
				modal : true,
				buttons : {
					'OK' : function() {
						$("#common_alert").dialog('close');
						return false;
					}
				}
			});
		}
		
		$("#common_alert").html(text.replace("\n", "<br />"));
		$("#common_alert").dialog('open');
	},

	dummy : null
};

/*************************************** クッキー処理 ***************************************/

Comment.Cookie = {};

Comment.Cookie.Object = function(){};

Comment.Cookie.Object.prototype = {
	name : "",
	range : "",
	comment : "",
	title : "",
	result: ""
};

Comment.Cookie.Util = {
	Write : function(name, value){
		targetStr = name + "=" + encodeURIComponent(value) + ";";
		var dt = new Date();
		dt.setDate(dt.getDate() + Const.Comment.COOKIE_EXPIREDAY);
		
		targetStr += "expires=" + dt.toGMTString() + ";";
		targetStr += "path=/;";
		
		document.cookie = targetStr;
	},
	
	Read : function(name){
		var allCookie = document.cookie;
		var arrayData = allCookie.split(";");
		var regex = new RegExp(" ", "g"); // 半角スペース除去

		var result = "";

		
		var key = name.replace(regex, "");

		var i = 0;
		while (arrayData[i]) {
			var word = arrayData[i].split("=");
			word[0] = word[0].replace(regex, "");
			if (key == word[0]) {
				result += decodeURIComponent(word[1]);
			}

			if (++i >= arrayData.length)
				break;
		}
		
		return result;
	},
	
	Load : function(name){
		var json = Comment.Cookie.Util.Read(name);
		
		try {
			var obj = JSON.parse(json);
			if(!obj)return;
			
			if(obj.name){
				$('#name').val(obj.name);
			}
			
			if(obj.comment){
				$('#comment').val(obj.comment);
			}
			
			if(obj.tilte){
				$('#macro_title').val(obj.title);
			}
			
			if(obj.range && obj.range.length > 0){
				$('.range').each(function(){
					if($(this).attr('value') == obj.range){
						$(this).attr('checked', 'checked');
					}
				});
			}
			
		} catch (e) {
			return;
		}
	},
	
	Save : function(name){
		var obj = new Comment.Cookie.Object();
		obj.name = $('#name').val();
		
		obj.comment = $('#comment').val();
		
		var range="";
		$('.range').each(function(){
			if($(this).attr('checked')){
				range = $(this).attr('value');
			}
		});
		obj.range = range;
		
		obj.result = $('#result_line').val();
		
		obj.title = $('#macro_title').val();
		
		var json = JSON.stringify(obj);
		Comment.Cookie.Util.Write(name, json);
		
		return obj;
	},
	
	Delete : function(name){
		targetStr = name + "=;";
		var dt = new Date();
		dt.setDate(dt.getDate() - 1);
		
		targetStr += "expires=" + dt.toGMTString() + ";";
		targetStr += "path=/;";
		
		document.cookie = targetStr;
	},
	
	Extend : function(name){
		var str = Comment.Cookie.Util.Read(name);
		Comment.Cookie.Util.Write(name, str);
	},
	
	dummy:null
};

/*************************************** ページ処理 ***************************************/

Comment.Object = function(){
	this._init();
};

Comment.Object.prototype = {

	_changeChatColor : function(){
		var range="";
		$('.range').each(function(){
			if($(this).attr('checked')){
				range = $(this).attr('value');
			}
		});
		
		
		if(range == "p"){
			$("#result_chat").css("color", "#01FFFF");
			return;
		}
		
		if(range == "a"){
			$("#result_chat").css("color", "#FFFF00");
			return;
		}
		
		if(range == "f"){
			$("#result_chat").css("color", "#02FB00");
			return;
		}
		
		if(range == "as"){
			$("#result_chat").css("color", "#FFBC5D");
			return;
		}
		
		if(range == "all"){
			$("#result_chat").css("color", "#FF2222");
			return;
		}
		
		$("#result_chat").css("color", "#FFFFFF");
		return;
	},
		
	_init : function(){

		var self = this;
		self._loadMyMacro();
		
		var disable = function(){
			$('#comment').attr('disabled', 'disabled');

			$('.type').each(function(){
				$(this).attr('disabled', 'disabled');
			});

			$('.range').each(function(){
				$(this).attr('disabled', 'disabled');
			});
			
			$('.range_dead').each(function(){
				$(this).attr('disabled', 'disabled');
			});

			$('#result_line').attr('value', '');
			$('#result_line').attr('disabled', 'disabled');
			
			$('#result_line_shortcut').attr('value', '');
			$('#result_line_shortcut').attr('disabled', 'disabled');

			$('#result_chat').html('');
			$('#result_balloon').html('');
			$('#result_balloon').hide();
			
			$('#macro_title').attr('disabled', 'disabled');
			$('#add_my_macro').attr('disabled', 'disabled');

		};

		var enable = function(){
			var str = $('#name').attr('value');
			var width = Comment.Util.getStrWidth(str);

			if(width < Const.Comment.CHARNAME_MIN_LENGTH){
				$('#name').css('background-color', '#FFF2F2');
				return Comment.Util.showMessage('キャラクター名が入力されていない、もしくは最小文字数より少ないです。');
			}
			

			if(width > Const.Comment.CHARNAME_MAX_LENGTH){
				$('#name').css('background-color', '#FFE2E2');
				return Comment.Util.showMessage('キャラクターの最大文字数をオーバーしています。');
			}
			
			$('#name').css('background-color', '#FFFFFF');
			
			Comment.Util.showMessage('');

			$('#comment').removeAttr('disabled');

			$('.range').each(function(){
				$(this).removeAttr('disabled');
			});
			
			var range = "";
			$('.range').each(function(){
				if($(this).attr('checked')){
					range = $(this).attr('value');
				}
			});
			
			if(range == "dc"){
				$('.range_dead').each(function(){
					$(this).removeAttr('disabled');
				});
			}
			else{
				$('.range_dead').each(function(){
					$(this).attr('disabled', 'disabled');
				});
			}

			$('#result_line').removeAttr('disabled');
			$('#result_line_shortcut').removeAttr('disabled');
			

			$('#macro_title').removeAttr('disabled');
			$('#add_my_macro').removeAttr('disabled');

			self._calcResult(self);
		};

		$('#name').focus(disable).blur(enable);
		$('#debug').click(function(){
			self._calcResult(self);
		});

		$('#comment').keyup(function(){
			self._calcResult(self);
		});

		$('.range').change(function(){
			
			if($(this).val() == "dc"){
				$('.range_dead').each(function(){
					$(this).removeAttr('disabled');
				});
			}
			else{
				$('.range_dead').each(function(){
					$(this).attr('disabled', 'disabled');
				});
			}
			
			self._calcResult(self);
		});
		
		$('.range_dead').change(function(){
			self._calcResult(self);
		});

		$('.type').change(function(){
			self._calcResult(self);
		});
		
		$('.macro_restore').live('click', function(){
			var cookie_name = $(this).attr('name');
			Comment.Cookie.Util.Load(cookie_name);
			self._calcResult(self);
		});
		
		$('.macro_delete').live('click', function(){
			var cookie_name = $(this).attr('name');
			Comment.Cookie.Util.Delete(cookie_name);
			
			$(this).parent().parent().remove();
		});
		
		$('#add_my_macro').click(function(){
			var addName = "";
			var names = Const.CookieNames;
			for(var i in names){
				var name = names[i];
				
				var already = Comment.Cookie.Util.Read(name);
				
				if(already.length == 0){
					addName = name;
					break;
				}
			}
			
			if(addName.length == 0){
				Comment.Util.alert("Myマクロに登録可能な件数は" + names.length + "件までです。");
				return;
			}
			
			var title = $("#macro_title").attr('value');
			if(title.length == 0){
				Comment.Util.alert("タイトルを入力してください。");
				return;
			}
			
			var obj = Comment.Cookie.Util.Save(addName);
			
			var addtr = $('#macro_tr').clone();
			addtr.removeAttr('id');
			addtr.show();
			addtr.children('.macro_title').text(obj.title);
			addtr.children('.macro_result').children('input').attr('value', obj.result);
			
			addtr.children('td').each(function(){
				$(this).children('input[type=button]').attr('name', addName);
			});
			
			$("#table_macro").append(addtr);
		});

		disable();
		enable();
	},
	
	_loadMyMacro : function(){
		
		var names = Const.CookieNames;
		for(var i in names){
			var name = names[i];
			var json = Comment.Cookie.Util.Read(name);
			
			if(json.length == 0)continue;
			
			try {
				var obj = JSON.parse(json);
				if(!obj)continue;
			}
			catch (e) {
				Comment.Cookie.Util.Delete(name);
				continue;
			}
			
			var addtr = $('#macro_tr').clone();
			addtr.removeAttr('id');
			addtr.show();
			addtr.children('.macro_title').text(obj.title);
			addtr.children('.macro_result').children('input').attr('value', obj.result);
			
			addtr.children('td').each(function(){
				$(this).children('input[type=button]').attr('name', name);
			});
			
			$("#table_macro").append(addtr);
			
			Comment.Cookie.Util.Extend(name);
		}
	},

	_calcResult : function(self){
		Comment.Cookie.Util.Save('DEFAULT');
		
		var range="";
		
		self._changeChatColor();
		
		$('.range').each(function(){
			if($(this).attr('checked')){
				range = $(this).attr('value');
			}
		});

		var addStr = "";
		if(range.length){
			addStr = "/" + range + " ";
			
			if(range =="dc"){
				var range_dead = "";
				$('.range_dead').each(function(){
				if($(this).attr('checked')){
						range_dead = $(this).attr('value');
					}
				});
				
				addStr = addStr + range_dead + " ";
			}
		}

		var str = "";
		var comment = $('#comment').attr('value');
		comment = comment.replace(/\r\n/g, "\n");
		
		var lines = comment.split("\n");

		// タイプを増やした場合ここで分岐
		for(var i in lines){
			str += Comment.Util.optimizeLine(lines[i]);
			if(i != (lines.length - 1)){
				str += '<br/>';
			}
		}

		// チャット用テキスト生成
		// 命令文と本文を結合した場合の文字数の確認（長すぎる場合は本文をカット）
		var strs = Comment.Util.splitStrLength(addStr + str , Const.Comment.STR_MAX_LENGTH );
		var optimize = strs[0];
		var resultStr = optimize.replace(addStr, "");
		$('#result_line').attr('value', addStr + resultStr);
		
		var overLineCount1 = strs[1].length;
		
		// ショートカット用テキスト生成
		strs = Comment.Util.splitStrLength(addStr + str , Const.Comment.SHORTCUT_MAX_LENGTH );
		optimize = strs[0];
		$('#result_line_shortcut').attr('value', addStr + optimize.replace(addStr, ""));
		
		var overLineCount2 = strs[1].length;
		
		// オーバーした分のコメントを表示
		var alert = '';
		
		if(overLineCount1){
			alert = 'チャット入力可能文字数を半角'+ overLineCount1 + '字分オーバーしています。';
			alert+= '（ショートカット入力可能文字数 半角' + overLineCount2 +'字分オーバー）';
		}
		else if(overLineCount2){
			alert = 'ショートカット入力可能文字数を半角'+ overLineCount2 + '字分オーバーしています。';
		}
		
		Comment.Util.showMessage(alert);
		
		resultStr = Comment.Util.optimizeShowLine(resultStr);
		self._showChat(resultStr);
		self._showBallon(resultStr);
	},

	_showChat : function(result){
		var name = $('#name').attr('value') + ':';

		var str = name;

		var nameLength = Comment.Util.getStrWidth(str);

		var remain = Const.Comment.WIDTH_LENGTH - nameLength;


		var text = "";
		var lineNumber = 1;
		
		while(true){
			var array = Comment.Util.splitStrLength(result, remain);

			text += str + array[0];
			str = " ";
			
			if(array[1].length == 0){
				break;
			}
			
			for(var i=1 ; i < nameLength ; i++){
				str += " ";
			}
			
			text += "\n";
			lineNumber++;

			result = array[1];
		}
		
		var userAgent = window.navigator.userAgent.toLowerCase();
		if (userAgent.indexOf('msie') != -1) {
			text = text.replace("\n", "\r\n");
		}

		
		//Comment.Util.changeTextArea('#result_chat', lineNumber);
		$('#result_chat').val(text);
	},

	_showBallon : function(result){
		/**
		 * <br/>タグを使った場合、デッドコメントの横幅制限は半角40文字です。
		 * <br/>タグまでの一行の長さが半角40文字を超えていた場合、
		 * 強制的に改行されます。
		 */
		$('#result_balloon').hide();
		
		if(result.length){
			$('#result_balloon').show();
		}
		
		text = "";
		
		var lines = result.split('<br/>');
		var maxwidth = 0;
		var lineNumber = 0;
		for(var i in lines){
			var line = lines[i];
			
			// 行中に何も記述されていない場合改行が無視される
			if(line.length == 0)continue;

			while(true){
				var array = Comment.Util.splitStrLength(line, Const.Comment.BALLON_LINE_LENGTH);

				var lineFix = array[0] + "\n";
				text += lineFix;
				lineNumber++;
				if(maxwidth < Comment.Util.getStrWidth(lineFix)){
					maxwidth = Comment.Util.getStrWidth(lineFix);
				}

				if(array[1].length == 0){
					break;
				}

				line = array[1];
			}
		}
		
		if(lineNumber == 0){
			lineNumber = 1;
		}
		
		Comment.Util.changeTextArea('#result_balloon', lineNumber, maxwidth-1);
		$('#result_balloon').val(text);
	},

	dummy: null
};

/*************************************** エントリーポイント ***************************************/

$(function(){
	Comment.Cookie.Util.Load('DEFAULT');
	new Comment.Object();
	
	// FAQ
	$("#button_faq_show").click(function(){
		$("#div_faq").show("fast");
	});
	
	$("#button_faq_hide").click(function(){
		$("#div_faq").hide("fast");
	});
});